<!DOCTYPE html>
<html lang="en" xmlns:v-demo="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <label>
        自定义焦点指令<input name="test" v-focus>
    </label>
    <!--使用自定义的v-red，在元素被插入时设置背景颜色为红色-->
    <hr>
    <div style="height: 200px;width: 200px" v-red></div>
    <!--演示自定义指令中的参数-->
    <hr>
    <div style="height: 200px;width: 200px" v-demo:foo.a.b="msg"></div>
    <!--自定义指令传值,会进到binding.value里-->
    <hr>
    <div  v-param="{title:'lady gaga',age:66}"></div>

</div>
<script src="lib/vue.js"></script>
<script>
    /**
     * 自定义一个全局指令，档元素被插入到DOM时会自动聚焦;
     *  钩子函数：
     *      bind：只调用一次，指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
     *      inserted：被绑定元素插入父节点时调用 (仅保证父节点存在，但不一定已被插入文档中)。
     *      update：所在组件的 VNode 更新时调用，但是可能发生在其子 VNode 更新之前。
     *          指令的值可能发生了改变，也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 。
     *  钩子函数的参数
     *      el：指令所绑定的元素，可以用来直接操作 DOM。
     *      binding：一个对象，包含以下属性：
     *          name：指令名，不包括 v- 前缀。
     *          value：指令的绑定值，例如：v-my-directive="1 + 1" 中，绑定值为 2。
     *          oldValue：指令绑定的前一个值，仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
     *          expression：字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中，表达式为 "1 + 1"。
     *          arg：传给指令的参数，可选。例如 v-my-directive:foo 中，参数为 "foo"。
     *          modifiers：一个包含修饰符的对象。例如：v-my-directive.foo.bar 中，修饰符对象为 { foo: true, bar: true }。
     *          vnode：Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
     *     oldVnode：上一个虚拟节点，仅在 update 和 componentUpdated 钩子中可用。
     * */
    Vue.directive('focus',{
        inserted: function (el) {
            alert(el.name);
            el.focus();
        }
    });
    let app = new Vue({
        el: '#app',
        data: {
            msg: 'test',
        },
        methods: {},
        // 自定义局部指令
        directives: {
            red:{
                inserted(el){
                    el.style.backgroundColor = 'red';
                }
            },
            param:{
              inserted(el,binding){
                  el.innerHTML = binding.value.title +'<br>' +
                                 binding.value.age+ '<br>';
              }
            },
            demo:{
                inserted(el,binding,vnode){
                    // 指令名称，没有v
                    binding.name;
                    // 绑定参数的值，也就是绑定的data中的数据的值,如 v-demo='msg' 则value=test
                    binding.value;
                    // 绑定的表达式，就时data中属性的名称,如 v-demo='msg' 则expression=msg
                    binding.expression;
                    // 调用指令时的参数,如 v-demo:foo ，则arguments=foo
                    binding.arguments;
                    // v-demo:foo.a.b -> {a:true,b:true}不知道有什么用
                    binding.modifiers;


                    var s = JSON.stringify;
                    el.innerHTML =
                        'name: '       + s(binding.name) + '<br>' +
                        'value: '      + s(binding.value) + '<br>' +
                        'expression: ' + s(binding.expression) + '<br>' +
                        'argument: '   + s(binding.arg) + '<br>' +
                        'modifiers: '  + s(binding.modifiers) + '<br>' +
                        'vnode keys: ' + Object.keys(vnode).join(', ')
                }
            }
        }
    })
</script>
</body>
</html>